package uk.ac.ebi.bioinvindex.model.impl;

import org.hibernate.annotations.Target;
import org.hibernate.search.annotations.*;
import uk.ac.ebi.bioinvindex.model.impl.processing.AssayImpl;
import uk.ac.ebi.bioinvindex.model.impl.term.DesignImpl;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;

/**
 * User: Nataliya Sklyar (nsklyar@ebi.ac.uk)
 * Date: Jun 21, 2007
 */

@Entity
@Table(name = "study")
@Indexed(index = "bii")
public class StudyImpl extends AnnotatableImpl{

	@Field(name = "title", index = Index.TOKENIZED, store = Store.YES)
	private String title;

	@Field(index = Index.TOKENIZED, store = Store.YES)
	private String description;

	@Field(index = Index.TOKENIZED, store = Store.YES)
	private String objective;

	@Target(DesignImpl.class)
	@IndexedEmbedded(prefix = "design_")
	@IndexedTarget(DesignImpl.class)
	private DesignImpl design;

	private Date submissionDate;

	private Date releaseDate;

	private Collection<ContactImpl> contacts = new HashSet<ContactImpl>();

	private Collection<InvestigationImpl> investigations = new HashSet<InvestigationImpl>();

	private Collection<PublicationImpl> publications = new HashSet<PublicationImpl>();

	@Target(AssayImpl.class)
	@IndexedEmbedded(prefix = "assay_")
	@IndexedTarget(AssayImpl.class)
	private Collection<AssayImpl> assays = new ArrayList<AssayImpl>();

	private Collection<ProtocolImpl> protocols = new ArrayList<ProtocolImpl>();

	public StudyImpl() {
	}

	public StudyImpl(String title) {
		this.title = title;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getObjective() {
		return objective;
	}

	public void setObjective(String objective) {
		this.objective = objective;
	}

	@ManyToOne(targetEntity = uk.ac.ebi.bioinvindex.model.impl.term.DesignImpl.class)
	@JoinColumn(name = "design", nullable = true)
	public DesignImpl getDesign() {
		return design;
	}

	public void setDesign(DesignImpl design) {
		this.design = design;
	}

	@Temporal(TemporalType.DATE)
	public Date getSubmissionDate() {
		return submissionDate;
	}

	public void setSubmissionDate(Date submissionDate) {
		this.submissionDate = submissionDate;
	}

	@Temporal(TemporalType.DATE)
	public Date getReleaseDate() {
		return releaseDate;
	}

	public void setReleaseDate(Date releaseDate) {
		this.releaseDate = releaseDate;
	}

	@OneToMany(targetEntity = uk.ac.ebi.bioinvindex.model.impl.processing.AssayImpl.class,
			mappedBy = "study")
	public Collection<AssayImpl> getAssays() {
		return assays;
	}

	public void addAssay(AssayImpl assay) {
		if (assay == null) {
			throw new IllegalArgumentException("assay cannot be null!");
		}
		assays.add(assay);
	}

	public boolean removeAssay(AssayImpl assay) {
		return assays.remove(assay);
	}

	protected void setAssays(Collection<AssayImpl> assays) {
		this.assays = assays;
	}

	@OneToMany(targetEntity = uk.ac.ebi.bioinvindex.model.impl.ContactImpl.class,
			mappedBy = "study")
	public Collection<ContactImpl> getContacts() {
		return contacts;
	}

	protected void setContacts(Collection<ContactImpl> contacts) {
		this.contacts = contacts;
	}

	public void addContact(ContactImpl contact) {
		contacts.add(contact);
	}


	@OneToMany(
			targetEntity = uk.ac.ebi.bioinvindex.model.impl.PublicationImpl.class,
			mappedBy = "study"
	)
	public Collection<PublicationImpl> getPublications() {
		return this.publications;
	}

	public void addPublication(PublicationImpl publication) {
		this.publications.add(publication);
	}

	protected void setPublications(Collection<PublicationImpl> publications) {
		this.publications = publications;
	}


	@ManyToMany(targetEntity = InvestigationImpl.class)
	@JoinTable(
			name = "STUDY2INVESTIGATION",
			joinColumns = {@JoinColumn(name = "STUDY_ID")},
			inverseJoinColumns = @JoinColumn(name = "INVESTIGATION_ID")
	)
	public Collection<InvestigationImpl> getInvestigations() {
		return investigations;
	}

	protected void setInvestigations(Collection<InvestigationImpl> investigations) {
		this.investigations = investigations;
	}

	public void addInvestigation(InvestigationImpl investigation) {
		this.investigations.add(investigation);
	}

	@ManyToMany(
			targetEntity = ProtocolImpl.class
	)
	@JoinTable(
			name = "Study2Protocol",
			joinColumns = {@JoinColumn(name = "STUDY_ID")},
			inverseJoinColumns = @JoinColumn(name = "PROTOCOL_ID")
	)
	public Collection<ProtocolImpl> getProtocols() {
		return this.protocols;
	}

	public void addProtocol(ProtocolImpl protocol) {
		this.protocols.add(protocol);
	}

	public boolean removeProtocol(ProtocolImpl protocol) {
		return protocols.remove(protocol);
	}

	protected void setProtocols(Collection<ProtocolImpl> protocols) {
		this.protocols = protocols;
	}

	@Override
	public String toString() {
		return "StudyImpl{" +
				"id ='" + getId() + '\'' +
				", acc ='" + getAcc() + '\'' +
				", title='" + title + '\'' +
				", description='" + description + '\'' +
				", objective='" + objective + '\'' +
				", design=" + design +
				", submissionDate=" + submissionDate +
				", releaseDate=" + releaseDate +
				", contacts=" + contacts +
				", assays=" + assays +
				", publications=" + publications +
				'}';
	}
}
